package com.yanqu.road.server.channelserver.manager.activity.tonbing.activity;

import com.yanqu.road.entity.activity.ActivityConditionInfo;
import com.yanqu.road.entity.activity.ActivityConfig;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.tonbingchannel.config.ChannelTonBingCampBoxConfig;
import com.yanqu.road.entity.activity.tonbingchannel.config.ChannelTonBingConfig;
import com.yanqu.road.entity.enums.activity.tonbing.eTonBingTaskType;
import com.yanqu.road.entity.enums.eActivityConfigType;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.logic.activity.tonbing.logic.TonBingMapLogic;
import com.yanqu.road.logic.bussiness.activity.ChannelTonBingActivityBusiness;
import com.yanqu.road.server.channelserver.manager.activity.ChannelActivityInfoMgr;
import com.yanqu.road.server.channelserver.manager.activity.tonbing.task.BaseChannelTonBingActivityTask;
import com.yanqu.road.server.manager.scene.CrossSceneMgr;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.DelayQueue;
import java.util.stream.Collectors;

/**
 * 放一些配置的东西
 */
public class ChannelTonBingBaseAc extends ChannelTonBingBase{

    protected static Logger logger = LogManager.getLogger(ChannelTonBingBaseAc.class.getName());

    // ============================== 锁 ==============================

    /**
     * 大锁
     */
    protected final Object lock = new Object();

    // ============================== 停线程 ==============================

    private boolean isStop = false;

    public void setStop(boolean stop) {
        isStop = stop;
    }

    // ============================== 定时器 ==============================

    /**
     * 单独线程
     */
    protected Thread thread = new Thread(new DelayQueueRun());

    protected class DelayQueueRun implements Runnable {
        @Override
        public void run() {
            while (true) {

                if (isStop) {
                    return;
                }

                try {
                    BaseChannelTonBingActivityTask task = taskQueue.take();

                    // 活动结束的任务：
                    if (task.getBeginTime() > config.getActivityInfo().getEndTime() * 1000L) {
                        if (task.getType() != eTonBingTaskType.SetWinner
                                && task.getType() != eTonBingTaskType.SendUnionHonor) {
                            continue;
                        }
                    }

                    // 正常执行
                    try {
                        task.run();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 定时器执行队列
     */
    protected DelayQueue<BaseChannelTonBingActivityTask> taskQueue = new DelayQueue<>();

    /**
     * 添加task，随便加，使用时会再校验时间
     */
    public void addTask(BaseChannelTonBingActivityTask task) {
        taskQueue.add(task);
    }

    // ============================== 配置 ==============================

    /**
     * 活动配置
     */
    protected ChannelTonBingConfig config;

    /**
     * 榜单长度
     */
    protected int userMaxRankConfig;
    protected int unionMaxRankConfig;
    protected int campMaxRankConfig;

    protected ChannelTonBingBaseAc(ActivityInfo activityInfo) {
        // 读配置库
        loadConfigFromDb(activityInfo);
        // 加场景
        CrossSceneMgr.initActivity(activityInfo);

        serverIdlIst = config.getActivityInfo().getServerIdList();
        channelIdList = StringUtils.stringToIntegerList(config.getActivityInfo().getParam6(),";");
    }

    public void loadConfigFromDb(ActivityInfo activityInfo) {
        initMaxRankConfig(activityInfo.getActivityId());

        Map<String, ActivityConfig> activityConfigMap = ChannelActivityInfoMgr.getConfigMap(activityInfo.getActivityId());

        ChannelTonBingConfig tmpConfig = new ChannelTonBingConfig();
        tmpConfig.setActivityInfo(activityInfo);

        tmpConfig.setBuffTypeConfigMap(ChannelTonBingActivityBusiness.getTonBingBuffTypeConfigMap(activityInfo.getActivityId()));

        tmpConfig.setCityTypeConfigMap(ChannelTonBingActivityBusiness.getTonBingCityTypeConfigMap(activityInfo.getActivityId()));

        tmpConfig.setCityConfigMap(ChannelTonBingActivityBusiness.getTonBingCityConfigMap(activityInfo.getActivityId()));

        tmpConfig.setNpcEventConfigMap(ChannelTonBingActivityBusiness.getTonBingNpcEventConfigMap(activityInfo.getActivityId()));

        tmpConfig.setTitleConfigMap(ChannelTonBingActivityBusiness.getTonBingTitleConfigMap(activityInfo.getActivityId()));

        tmpConfig.setZiZhongItem(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_ITEM_CARGO.getName()).getIntValue());
        tmpConfig.setZhanGongItem(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_ITEM_SCORE.getName()).getIntValue());
        tmpConfig.setShenXingItem(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_ITEM_WALK_QUICKEN.getName()).getIntValue());
        tmpConfig.setZhanGuItem(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_ITEM_WAR_DRUM.getName()).getIntValue());
        tmpConfig.setBingFuItem(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_ITEM_SOLDIERS.getName()).getIntValue());

        String soldierRecruitParam = activityConfigMap.get(eActivityConfigType.PEAKTONGBING_SOLDIER_COST.getName()).getValue();
        Map<Long, Long> recruitSoldierMap = new ConcurrentHashMap<>();
        for (String tmpParam : StringUtils.stringToStringList(soldierRecruitParam, "\\|")) {
            List<Long> list = StringUtils.stringToLongList(tmpParam, ";");
            recruitSoldierMap.put(list.get(1), list.get(0));
        }
        tmpConfig.setRecruitSoldierMap(recruitSoldierMap);

        tmpConfig.setBattleCostTime(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_BATTLE_TIME.getName()).getIntValue() * DateHelper.SECOND_MILLIONS);

        tmpConfig.setCityEventConfigList(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_CITY_EVENT.getName()).getIntListValue(";"));

        tmpConfig.setCityEventInitConfigList(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_CITY_EVENT_INIT.getName()).getIntListValue("\\|"));

        List<String> cityEventTimeParam = StringUtils.stringToStringList(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_CITY_EVENT_TIME.getName()).getValue(), "\\|");
        List<Integer> cityEventTimeParam1 = StringUtils.stringToIntegerList(cityEventTimeParam.get(0), ";");
        List<Integer> cityEventTimeParam2 = StringUtils.stringToIntegerList(cityEventTimeParam.get(1), ";");
        tmpConfig.setCityEventRefreshTime(cityEventTimeParam1.stream().mapToLong(item -> item * DateHelper.HOUR_MILLIONS).boxed().collect(Collectors.toList()));
        tmpConfig.setCityEventApplyTime(cityEventTimeParam2.stream().mapToLong(item -> item * DateHelper.HOUR_MILLIONS).boxed().collect(Collectors.toList()));

        tmpConfig.setMoveTime(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_CITY_MOVE_TIME.getName()).getLongValue() * DateHelper.SECOND_MILLIONS);
        tmpConfig.setMoveTimeFast(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_OWN_CITY_MOVE_TIME.getName()).getLongValue() * DateHelper.SECOND_MILLIONS);

        tmpConfig.setWoundedSoldierMaxNum(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_WOUNDED_SOLDIER_NUM_LIMIT.getName()).getLongValue());

        tmpConfig.setWoundedSoldierPercent(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_WOUNDED_SOLDIER_CONVERT_RATE.getName()).getLongValue());

        List<Integer> woundedRescueParam = activityConfigMap.get(eActivityConfigType.PEAKTONGBING_WOUNDED_SOLDIER_RESCUE_SPEED.getName()).getIntListValue(";");
        tmpConfig.setWoundedRescueTime(woundedRescueParam.get(1) * DateHelper.SECOND_MILLIONS);
        tmpConfig.setWoundedRescueCount(woundedRescueParam.get(0));

        tmpConfig.setNpcEventMaxNum(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_NPC_EVENT_EXIST_NUM_LIMIT.getName()).getIntValue());
        tmpConfig.setNpcEventInterval(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_NPC_EVENT_REFRESH_INTERVAL.getName()).getIntValue() * DateHelper.HOUR_MILLIONS);
        tmpConfig.setNpcEventDayMaxNum(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_NPC_EVENT_NUM_LIMIT.getName()).getIntValue());
        tmpConfig.setNpcEventBeginTime(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_NPC_EVENT_REFRESH_TIME.getName()).getIntValue() * DateHelper.HOUR_MILLIONS);

        List<Integer> joinParam = activityConfigMap.get(eActivityConfigType.PEAKTONGBING_CAMP_RULE.getName()).getIntListValue(";");
        tmpConfig.setUnionNum(joinParam.get(0));
        tmpConfig.setCampNum(joinParam.get(1));

        List<Integer> createTimeParam = activityConfigMap.get(eActivityConfigType.PEAKTONGBING_CREATE_TEAM_TIME.getName()).getIntListValue(";");
        List<Long> joinTimeList = new ArrayList<>();
        joinTimeList.add(activityInfo.getBeginTime() * 1000L + (createTimeParam.get(0) - 1) * DateHelper.DAY_MILLIONS + createTimeParam.get(1) * DateHelper.HOUR_MILLIONS);
        joinTimeList.add(activityInfo.getBeginTime() * 1000L + (createTimeParam.get(0) - 1) * DateHelper.DAY_MILLIONS + createTimeParam.get(2) * DateHelper.HOUR_MILLIONS);
        tmpConfig.setJoinTimeList(joinTimeList);

        List<String> stage1TimeParam = activityConfigMap.get(eActivityConfigType.PEAKTONGBING_FIRST_STAGE_TIME.getName()).getStringListValue("\\|");
        List<List<Long>> stage1TimeList = new ArrayList<>();
        for (String tmp : stage1TimeParam) {
            List<Integer> tmpList = StringUtils.stringToIntegerList(tmp, ";");
            List<Long> stage1Time = new ArrayList<>();
            stage1Time.add(activityInfo.getBeginTime() * 1000L + (tmpList.get(0) - 1) * DateHelper.DAY_MILLIONS + tmpList.get(1) * DateHelper.HOUR_MILLIONS);
            stage1Time.add(activityInfo.getBeginTime() * 1000L + (tmpList.get(0) - 1) * DateHelper.DAY_MILLIONS + tmpList.get(2) * DateHelper.HOUR_MILLIONS);
            //开始时间，用来生成轮次数据
            stage1Time.add(activityInfo.getBeginTime() * 1000L + (tmpList.get(0) - 1) * DateHelper.DAY_MILLIONS);
            stage1Time.add(activityInfo.getBeginTime() * 1000L + (tmpList.get(0)) * DateHelper.DAY_MILLIONS);
            stage1TimeList.add(stage1Time);
        }
        tmpConfig.setStage1TimeList(stage1TimeList);
        tmpConfig.setWarTypeCount(stage1TimeParam.size());

        Map<Integer,Long> tempStage2BeginTimeMap = new ConcurrentHashMap<>();
        List<String> stage2ParamStrList = activityConfigMap.get(eActivityConfigType.PEAKTONGBING_SECOND_STAGE_TIME.getName()).getStringListValue("\\|");
        for(String stage2ParamStr : stage2ParamStrList){
            List<Integer> stage2Param = StringUtils.stringToIntegerList(stage2ParamStr,";");
            tempStage2BeginTimeMap.put(stage2Param.get(0),activityInfo.getBeginTime() * 1000L + (stage2Param.get(0) - 1) * DateHelper.DAY_MILLIONS + stage2Param.get(1) * DateHelper.HOUR_MILLIONS);
        }
        tmpConfig.setStage2BeginTimeMap(tempStage2BeginTimeMap);

        tmpConfig.setTeamAuxiliaryPatronsNum(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_PLAYER_TEAM_LIEUTENANT_NUM.getName()).getIntValue());

        Map<Integer, ChannelTonBingCampBoxConfig> campBoxConfigMap = new ConcurrentHashMap<>();
        for (String campBoxPara : StringUtils.stringToStringList(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_CAMP_GIFT_BAG.getName()).getValue(), "\\|")) {
            List<Integer> list = StringUtils.stringToIntegerList(campBoxPara, ";");
            ChannelTonBingCampBoxConfig campBoxConfig = new ChannelTonBingCampBoxConfig();
            campBoxConfig.setKey(list.get(0));
            campBoxConfig.setBoxId(list.get(1));
            campBoxConfig.setBoxScore(list.get(2));
            campBoxConfigMap.put(campBoxConfig.getKey(), campBoxConfig);
        }
        tmpConfig.setCampBoxConfigMap(campBoxConfigMap);

        List<Long> list = StringUtils.stringToLongList(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_TEAM_NUM_LIMIT_PARAM.getName()).getValue(), ";");
        tmpConfig.setTeamSoldierMaxNumParam(list);

        tmpConfig.setTeamNumLowerLimitParam(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_TEAM_NUM_LOWER_LIMIT_PARAM.getName()).getLongValue());
        tmpConfig.setTeamNumLowerLimitFixedParam(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_TEAM_NUM_LOWER_LIMIT_FIXED_PARAM.getName()).getLongValue());

        tmpConfig.setBattleParam(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_SOLDIER_LOST_PARAM.getName()).getIntListValue(";"));

        tmpConfig.setZhanGongParam(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_ITEM_SCORE_PARAM.getName()).getIntListValue(";"));

        tmpConfig.setContinueWinReportTimes(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_BARRAGE_STREAK_NUM.getName()).getIntValue());

        tmpConfig.setNeedHelpCd(DateHelper.HOUR_MILLIONS * activityConfigMap.get(eActivityConfigType.PEAKTONGBING_HELP_TIME.getName()).getIntValue());

        tmpConfig.setUserReportNum(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_PERSONAL_BATTLE_REPORT_NUM_LIMIT.getName()).getIntValue());
        tmpConfig.setCityReportNum(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_CAMP_BATTLE_REPORT_NUM_LIMIT.getName()).getIntValue());

        List<String> lightParam = StringUtils.stringToStringList(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_SPECIAL_SHOW.getName()).getValue(), "\\|");
        int lightNum = StringUtils.stringToIntegerList(lightParam.get(lightParam.size() - 1), ";").get(1);
        tmpConfig.setLightRankNum(lightNum);

        tmpConfig.setBarrackLimitParam(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_BARRACK_NUM_LIMIT_PARAM.getName()).getIntValue());

        String worshipRewardStr = activityConfigMap.get(eActivityConfigType.PEAKTONGBING_WORSHIP_REWARD_PARAM.getName()).getValue();
        Map<Integer, List<Integer>> worshipRewardMap = new ConcurrentHashMap<>();
        for (String tmpParam : StringUtils.stringToStringList(worshipRewardStr, "\\|")) {
            List<String> strList = StringUtils.stringToStringList(tmpParam, "=");
            List<Integer> intList = StringUtils.stringToIntegerList(strList.get(1), ";");
            worshipRewardMap.put(Integer.valueOf(strList.get(0)), intList);
        }
        tmpConfig.setWorshipRewardMap(worshipRewardMap);

        tmpConfig.setWinDecorationId(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_FIRST_TITLE_ID.getName()).getIntValue());

        List<Integer> showParam = activityConfigMap.get(eActivityConfigType.PEAKTONGBING_SCREEN_SHOW_RULE.getName()).getIntListValue("\\|");
        tmpConfig.setShowCampInScreenNum(showParam.get(0));
        tmpConfig.setShowCampOutScreenNum(showParam.get(1));

        tmpConfig.setShowCampTopNum(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_TEAM_SHOW_RULE.getName()).getIntValue());

        tmpConfig.setMailFirstTitleReward(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_MAIL_FIRST_TITLE_REWORD.getName()).getValue());
        tmpConfig.setMailFirstContentReward(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_MAIL_CONTENT_FIRST_REWORD.getName()).getValue());
        tmpConfig.setMailWinTitleReward(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_MAIL_WIN_TITLE_REWORD.getName()).getValue());
        tmpConfig.setMailWinContentReward(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_MAIL_CONTENT_WIN_REWORD.getName()).getValue());

        tmpConfig.setBattlefieldPartParam(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_BATTLE_PLACE_PARAM.getName()).getIntValue());

        tmpConfig.setBattlePrepareTime(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_BATTLE_READY_TIME.getName()).getLongValue() * DateHelper.SECOND_MILLIONS);

        tmpConfig.setSyncPatronsCd(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_POWER_COOL_DOWN_TIME.getName()).getLongValue() * DateHelper.HOUR_MILLIONS);

        tmpConfig.setCityDefTeamNameKey(eActivityConfigType.PEAKTONGBING_CITY_SOLDIER_NAME.getName()); // 相当于写死

        tmpConfig.setCityTeamRecoveryTime(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_CITY_SOLDIER_RECOVER_TIME.getName()).getLongValue() * DateHelper.SECOND_MILLIONS);

        tmpConfig.setLightNeedZhanGong(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_LIGHT_NEED_ZHANGONG.getName()).getLongValue());

        tmpConfig.setRedDotCollectCount(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_RED_DOT_COLLECT_COUNT.getName()).getLongValue());

        tmpConfig.setRedDotCureNum(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_RED_DOT_CURE_NUM.getName()).getLongValue());

        tmpConfig.setZiZhongTitle(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_MAIL_TITLE_FOOD_REWORD.getName()).getValue());
        tmpConfig.setZiZhongContent(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_MAIL_CONTENT_FOOD_REWORD.getName()).getValue());
        tmpConfig.setAppointScoreLimit(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_APPOINT_ITEM_SCORE_LIMIT.getName()).getLongValue());

        tmpConfig.setSkinsExchangeParam(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_SKINS_EXCHANGE_PARAM.getName()).getValue());

        // 这两个不读库
        tmpConfig.setNpcEventPositionNum(TonBingMapLogic.getNpcEventPosNumConfig());
        tmpConfig.setCityConnectMap(TonBingMapLogic.getCityConnectMapConfig());


        //统兵演武新加的
        tmpConfig.setGroupRuleList(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_GROUP_RULE.getName()).getValue());
        tmpConfig.setUnionMax(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_GROUP_CHAMBER_NUM_MAX.getName()).getIntValue());

        tmpConfig.setWarTypeList(activityConfigMap.get(eActivityConfigType.PEAKTONGBING_CITY_TYPE.getName()).getIntListValue("\\|"));

        config = tmpConfig;
    }

    public ChannelTonBingConfig getConfig() {
        return config;
    }

    private void initMaxRankConfig(int activityId) {
        userMaxRankConfig = getMaxRankConfig(ChannelActivityInfoMgr.getConditionInfoList(activityId, eGamePlayerEventType.TonBingUserZhanGongRank.getValue()));
        unionMaxRankConfig = getMaxRankConfig(ChannelActivityInfoMgr.getConditionInfoList(activityId, eGamePlayerEventType.TonBingCampUnionZhanGongRank.getValue()));
        campMaxRankConfig = getMaxRankConfig(ChannelActivityInfoMgr.getConditionInfoList(activityId, eGamePlayerEventType.TonBingCampScoreRank.getValue()));
    }

    private int getMaxRankConfig(List<ActivityConditionInfo> list) {
        int maxRank = 0;
        for (ActivityConditionInfo conditionInfo : list) {
            int tmp = conditionInfo.getParamList().get(1).intValue();
            if (tmp > 0 && maxRank < tmp) {
                maxRank = tmp;
            }
        }
        return maxRank;
    }
}
